<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html; charset=ISO-8859-1"
 http-equiv="content-type">
  <title>Verb Tutorial</title>
  <link rel="icon" href="./favicon.ico" type="image/x-icon">
  <link rel="shortcut icon" href="./favicon.ico" type="image/x-icon">
</head>
<body>
<pre style="font-family: courier new,courier,monospace;"><big><big><big
 style="font-weight: bold;">The Verb</big></big><br><br><span
 style="font-style: italic; font-weight: bold;">Note: This page is for advanced coders who need to </span><br
 style="font-style: italic; font-weight: bold;"><span
 style="font-style: italic; font-weight: bold;">create new verbs, or modify existing ones. Newbie</span><br
 style="font-style: italic; font-weight: bold;"><span
 style="font-style: italic; font-weight: bold;">coders should not assume they need to know anything</span><br
 style="font-style: italic; font-weight: bold;"><span
 style="font-style: italic; font-weight: bold;">here.</span> <br><br>	The verb is like anything else. Exactly as<br>good as you make it, no more and no less. Deconstructing<br>a new verb for the first time can be confusing, but <br>in doing so you will gain a better understanding of<br>the parsing system Dead Souls uses. <br><br>	Please note, if there's anything here hard to<br>follow or understand, you need to review the Creator's<br>Manual for key LPC concepts.<br><br><br><a
 href="#1">The verb itself</a><br><br><a href="#2">Rules and tokens</a><br><br><a
 href="#3">can's and do's</a><br><br><a href="#4">The object: direct_ and indirect_</a><br><br><a
 href="#5">References</a><br><br><br><span
 style="font-weight: bold; text-decoration: underline;"><a name="1"></a>The verb itself</span><br><br>Let's take a look at the code for a verb, and dissect<br>it for meaning. <br></big></pre>
<pre style="font-family: courier new,courier,monospace;"><big><span
 style="color: rgb(0, 102, 0);">#include &lt;lib.h&gt;</span><br
 style="color: rgb(0, 102, 0);"><br style="color: rgb(0, 102, 0);"><span
 style="color: rgb(0, 102, 0);">inherit LIB_VERB;</span><br
 style="color: rgb(0, 102, 0);"><br style="color: rgb(0, 102, 0);"><span
 style="color: rgb(0, 102, 0);">static void create() {</span><br
 style="color: rgb(0, 102, 0);"><span style="color: rgb(0, 102, 0);">    verb::create();</span><br
 style="color: rgb(0, 102, 0);"><span style="color: rgb(0, 102, 0);">    SetVerb("buy");</span><br
 style="color: rgb(0, 102, 0);"><span style="color: rgb(0, 102, 0);">    SetSynonyms("purchase");</span><br
 style="color: rgb(0, 102, 0);"><span style="color: rgb(0, 102, 0);">    SetRules("STR from LIV");</span><br
 style="color: rgb(0, 102, 0);"><span style="color: rgb(0, 102, 0);">    SetErrorMessage("Buy what from whom?");</span><br
 style="color: rgb(0, 102, 0);"><span style="color: rgb(0, 102, 0);">    SetHelp("Syntax: &lt;buy ITEM from VENDOR&gt;\n\n"</span><br
 style="color: rgb(0, 102, 0);"><span style="color: rgb(0, 102, 0);">      "Blah blah this is the help message.");</span><br
 style="color: rgb(0, 102, 0);"><span style="color: rgb(0, 102, 0);">}</span><br
 style="color: rgb(0, 102, 0);"><br style="color: rgb(0, 102, 0);"><span
 style="color: rgb(0, 102, 0);">mixed can_buy_str_from_liv(string str) {</span><br
 style="color: rgb(0, 102, 0);"><span style="color: rgb(0, 102, 0);">    if( this_player()-&gt;GetParalyzed() ) {</span><br
 style="color: rgb(0, 102, 0);"><span style="color: rgb(0, 102, 0);">        return "You cannot do anything.";</span><br
 style="color: rgb(0, 102, 0);"><span style="color: rgb(0, 102, 0);">    }</span><br
 style="color: rgb(0, 102, 0);"><span style="color: rgb(0, 102, 0);">    return this_player()-&gt;CanManipulate();</span><br
 style="color: rgb(0, 102, 0);"><span style="color: rgb(0, 102, 0);">}</span><br
 style="color: rgb(0, 102, 0);"><br style="color: rgb(0, 102, 0);"><span
 style="color: rgb(0, 102, 0);">mixed do_buy_str_from_liv(string str, object vendor) {</span><br
 style="color: rgb(0, 102, 0);"><span style="color: rgb(0, 102, 0);">    return vendor-&gt;eventSell(this_player(), remove_article(lower_case(str)));</span><br
 style="color: rgb(0, 102, 0);"><span style="color: rgb(0, 102, 0);">}</span><br><br><br>	If you never looked at a verb before, it can<br>look rather alien and disgusting, like a dead facehugger.<br>But like the facehugger, it's actually quite beautiful<br>in its own way.<br>	Let's dissect and comment it now:<br><br><br><span
 style="color: rgb(0, 102, 0); font-weight: bold;">#include &lt;lib.h&gt; </span><br>// This include statement allows us to use macros, or nicknames, <br>// for certain things. Specifically, the lib include gives us<br>// knowledge of what we mean by LIB_VERB.<br><br><span
 style="color: rgb(0, 102, 0); font-weight: bold;">inherit LIB_VERB;</span><br>// This line tells us that we will be inheriting all the<br>// functions and variables defined in /lib/verb.c .<br><br
 style="color: rgb(0, 102, 0);"><span
 style="color: rgb(0, 102, 0); font-weight: bold;">static void create() {</span><br>// The create function is like main() in C/C++. A function that<br>// is *always* called when an object is loaded. Therefore,<br>// anything important goes inside here.<br><br
 style="font-weight: bold;"><span
 style="color: rgb(0, 102, 0); font-weight: bold;">    verb::create();</span><br>// The :: operator is called the "scope resolution operator".<br>// That's a fancy way of saying that we are trying to use<br>// a function that exists somewhere in the inheritance tree, and<br>// not in this individual file. The verb::create() line above<br>// is saying "At this point, execute any directives in the<br>// create() function of LIB_VERB". This is necessary because <br>// the create() function we define here will override the create()<br>// function we inherit, and that overridden function might have<br>// had important stuff in it we need to have happen. <br>//    If you didn't understand any of that, you should probably<br>// stop reading this tutorial and get started on reading<br>// the Creator's manual.<br><br><span
 style="color: rgb(0, 102, 0); font-weight: bold;">    SetVerb("buy");</span><br>// This identifies what word the parser should associate<br>// with this verb.<br><br><span
 style="color: rgb(0, 102, 0);">    <span style="font-weight: bold;">SetSynonyms("purchase");</span></span><br>// Self explanatory. This is where you specify words with a<br>// similar meaning that should also be associated with this verb.<br><br><span
 style="color: rgb(0, 102, 0); font-weight: bold;">    SetRules("STR from LIV");</span><br>// Here's one of the new and exotic features of verbs. Rules and tokens.<br>// When the parser catches the "buy" word from the user's input, <br>// it will check to see if the rest of the words in the<br>// command line conform the the known set of rules for the verb.<br>// if they don't, the parser will error. We'll go over the rules<br>// a bit further on.<br><br
 style="color: rgb(0, 102, 0); font-weight: bold;"><span
 style="color: rgb(0, 102, 0); font-weight: bold;">    SetErrorMessage("Buy what from whom?");</span><br>// By default, the parser's error messages aren't terribly<br>// descriptive or helpful...usually it's along the lines <br>// of "You can't X the Y". The line above lets you provide the<br>// user a clue as to how to better avail themselves of the <br>// verb's functionality.<br><br><span
 style="font-weight: bold; color: rgb(0, 102, 0);">    SetHelp("Blah blah this is the help message.");</span><br>// When the user types "help buy", this is what they get.<br><br>// The create function ends here, with the close brace<br>// below this line.<br><span
 style="color: rgb(0, 102, 0); font-weight: bold;">}</span><br><br><br
 style="font-weight: bold;"><span
 style="color: rgb(0, 102, 0); font-weight: bold;">mixed can_buy_str_from_liv(string str) {</span><br>// This function does some very rudimentary checks of<br>// whether the user can use the verb. The can_* type<br>// functions will be discussed in more detail a bit <br>// further on.<br><br
 style="color: rgb(0, 102, 0); font-weight: bold;"><span
 style="color: rgb(0, 102, 0); font-weight: bold;">    if( this_player()-&gt;GetParalyzed() ) {</span><br
 style="color: rgb(0, 102, 0); font-weight: bold;"><span
 style="color: rgb(0, 102, 0); font-weight: bold;">        return "You cannot do anything.";</span><br
 style="color: rgb(0, 102, 0); font-weight: bold;"><span
 style="color: rgb(0, 102, 0); font-weight: bold;">    }</span><br>// Pretty self-explanatory. An obvious check.<br><br><span
 style="color: rgb(0, 102, 0); font-weight: bold;">    return this_player()-&gt;CanManipulate();</span><br>// The player object has a CanManipulate() function. If<br>// the player has no prehensile limbs (i.e. "wielding limbs", <br>// like hands) then the  CanManipulate() function in their<br>// object returns 0. Since the line above returns whatever<br>// CanManipulate() returns, that means that if the player<br>// is missing both hands, he can't sell anything. The verb<br>// will fail.<br><br
 style="color: rgb(0, 102, 0); font-weight: bold;"><span
 style="color: rgb(0, 102, 0); font-weight: bold;">mixed do_buy_str_from_liv(string str, object vendor) {</span><br>// Like the can_* functions, do_ functions will get more<br>// treatment further on. This is generally where the actual<br>// "doing" of the verb gets fired off, if appropriate.<br
 style="font-weight: bold; color: rgb(0, 102, 0);"><br
 style="font-weight: bold; color: rgb(0, 102, 0);"><span
 style="font-weight: bold; color: rgb(0, 102, 0);">    return vendor-&gt;eventSell(this_player(), remove_article(lower_case(str)));</span><br>// Did you notice that this function is declared as type "mixed"?<br>// This allows us to return weird stuff, like in this case where<br>// we're returning the result of a function call. We're not<br>// 100% sure what data type eventSell() in the vendor returns,<br>// so mixed covers all the bases. Whatever eventSell() returns,<br>// that's what gets returned here. If the parser got this far,<br>// then the verb's execution was successful.<br>//	That doesn't necessarily mean that the player successfully<br>// sold anything. It may be he lacks enough quatloos for the<br>// shizbat. But that is no concern of the verb. That is the<br>// business of the eventSell() function it called on the vendor.<br><span
 style="color: rgb(0, 102, 0); font-weight: bold;">}</span><br><br><br><span
 style="font-weight: bold; text-decoration: underline;"><a name="2"></a>Rules and tokens</span><br><br>	By a magic I do not fully understand myself, the<br>parser (which lives in the compiled driver binary, meaning<br>it was written in C and therefore inscrutable to me) can<br>actually work out from your command line what object you meant<br>to do what to with what. <br><br>	For example, if you are in a room full of orcs,<br>and you type:<br><br><span
 style="font-weight: bold;">kill orcs</span><br><br>	The parser actually susses out that orcs are objects<br>in your environment, and that you intend to act on more than<br>one of them. The parser will go on to check the attack verb<br>for its known rules. The rules for "attack" look like this:<br><br
 style="font-weight: bold; color: rgb(0, 102, 0);"><span
 style="font-weight: bold; color: rgb(0, 102, 0);">SetRules("LVS", "only LVS","LVS only")</span><br><br>	The parser sees that you meant two objects that <br>are living, and sure enough, the attack verb will accept<br>"multiple living things" as a rule. In this case, the<br>matched rule is the first one, with the token LVS.<br><br>	Hold on there, you say. What if I typed <span
 style="font-weight: bold;">kill orc</span> , <br>in the singular? This would still match the first rule, <br>because LVS doesn't just stand for "multiple living things".<br>It's rather more like "one or more living things". <br><br>	If the first attack token were LIV instead, then<br>killing a singular orc would succeed in the parser, but <br>killing plural orcs would probably fail.<br><br>	The second rule has two tokens. One is an object<br>token, LVS, where object is meant in a semi-grammatical sense.<br>The other is a prepositional token, which is also meant in<br>a semi-grammatical sense. <br><br>	The way "object" and "preposition" are handled in<br>the parser's grammar is not the way they are handled in<br>English grammar. For example, you may be feeling indignant<br>at being told that "only" is a preposition. Obviously, in<br>English, it isn't. However, the parser isn't as linguistically<br>sophisticated as you. For the parser, anything used <br>periverbally that isn't an object is a preposition. Please don't<br>email me telling me I don't know my English grammar. When I<br>talk subject, object, and preposition here, I am using<br>the parser's simplified grammar.<br><br>	As you might have guessed, an "object token" in this case<br>is the noun that the verb will be working with. Note that the<br>subject is assumed to be the caller, or player, that invoked the<br>verb's execution, and does not have an explicit token identified.<br><br>	So, back to our second rule. "only LVS" means that<br>I can issue a command like this:<br><br
 style="font-weight: bold;"><span style="font-weight: bold;">kill only the second orc</span><br><br>	And the parser will not reject it. However, failing<br>to use the preposition token explicitly allowed in a rule <br>will cause the parser to error. Trying to:<br><br
 style="font-weight: bold;"><span style="font-weight: bold;">kill merely the second orc</span><br><br>will not bring joy.<br><br>The known object tokens are:<br><br><span
 style="font-weight: bold; color: rgb(0, 102, 0);">LIV</span><span
 style="color: rgb(0, 102, 0);"> </span>- one living thing<br><span
 style="font-weight: bold; color: rgb(0, 102, 0);">LVS</span><span
 style="color: rgb(0, 102, 0);"> </span>- one or more living things<br><span
 style="font-weight: bold; color: rgb(0, 102, 0);">OBJ</span><span
 style="color: rgb(0, 102, 0);"> </span>- one object<br><span
 style="font-weight: bold; color: rgb(0, 102, 0);">OBS</span><span
 style="color: rgb(0, 102, 0);"> </span>- one or more objects<br><span
 style="font-weight: bold; color: rgb(0, 102, 0);">STR</span><span
 style="color: rgb(0, 102, 0);"> </span>- a string of characters<br><span
 style="font-weight: bold; color: rgb(0, 102, 0);">WRD</span> - a generic thing that may be a string, object, or living thing<br><br>To get a list of known preposition tokens, type:<br><br
 style="font-weight: bold;"><span style="font-weight: bold;">eval return MASTER_D-&gt;parse_command_prepos_list()</span><br><br><br><span
 style="text-decoration: underline; font-weight: bold;"><a name="3"></a>can's and do's</span><br><br>	Following the create() fun you saw two types of functions:<br>can_* and do_*. These are sometimes called "applies". When you see <br>someone referring to an apply, they mean a function called by the driver.<br><br>	Notionally, the can_ applies are meant to test the<br>validity of the verb's execution, and the do_ applies are<br>meant to perform the actions required.<br><br>	In practice, this is only somewhat the case. Whether<br>it's a bug or feature, the can_ applies tend to mangle the<br>arguments they receive. Pretty much no matter what the<br>argument is, it gets turned into a string. It's a peculiar<br>"gotcha" that will have you spinning your wheels for a long time<br>if you don't happen to know it.<br><br>	That doesn't mean the can_ applies are useless. They are<br>in fact necessary. If the can_ apply doesn't exist, or doesn't<br>return a positive integer, the do_ apply won't happen, meaning your<br>verb won't execute. Since the can_ applies are somewhat hobbled,<br>use them for quick, obvious sanity checks, like "is this<br>player dead" or "does she have hands to manipulate anything with".<br><br>	If you need to do a check, for example, to ensure that<br>the vendor is an elf, that means that you need to make a<br>call to that vendor object. Since the can_ applies won't<br>handle object arguments, this check will need to happen in the<br>do_ function.<br><br>Some examples of can_ and do_ verb applies:<br><br><span
 style="font-weight: bold; color: rgb(0, 102, 0);">can_throw_obj()</span><br><br>Pretty obvious. The command in question would be something<br>like "throw switch" perhaps. <br><br
 style="font-weight: bold;"><span
 style="font-weight: bold; color: rgb(0, 102, 0);">can_throw_obj_word_obj()</span><br><br>A little trickier. Now we're allowing for a wildcard prepositional token. Here<br>the command might be "throw ball at benny", but because the token<br>is not explicitly listed (that would be </big><big>something like <span
 style="color: rgb(0, 102, 0); font-weight: bold;">can_throw_obj_at_obj()</span>)<br>and the target is not explicitly a living thing, this apply<br>also matches "throw the sword in the lake". Note it won't match<br>"throw the jacks on the floor".<br><br></big><big><br><span
 style="font-weight: bold; color: rgb(0, 102, 0);">do_read_str_on_obj(string str, object ob)</span><br><br>If your verb has a <span
 style="font-weight: bold; color: rgb(0, 102, 0);">can</span></big><big
 style="font-weight: bold; color: rgb(0, 102, 0);">_read_str_word_obj(</big><big
 style="font-weight: bold; color: rgb(0, 102, 0);">string str, object ob</big><big><span
 style="font-weight: bold; color: rgb(0, 102, 0);">)</span> apply that <br>returned 1, then this sweet baby gets called. Presumably here you'd<br>have the verb call the object and tell it to do something with the<br>arguments provided. Here is where the actual <span
 style="font-style: italic;">reading action</span> begins.<br><br><br>	Alas, the work of parser applies is not done. The object in<br>question must have matching direct_ and indirect_ applies, otherwise,<br>error occurs. These applies are discussed in the next section.<br></big><big><br><br>	<br><span
 style="font-weight: bold; text-decoration: underline;"><a name="4"></a>The object: direct_ and indirect_</span><br><br>	As you can see, the thing that gives a do_ apply<br>its whammy is a call to an object. That's the point of a verb,<br>is doing something, and in the case above, its:<br><br><span
 style="font-weight: bold; color: rgb(0, 102, 0);">return vendor-&gt;eventSell(this_player(), remove_article(lower_case(str)));</span><br><br>	However, if you make a verb like this, and then<br>just try to use it, it'll fail. This is because the driver<br>needs the objects it acts on to have applies that<br>correspond to the do_ applies.<br><br>	The corresponding applies are direct_ and indirect_ ,<br>and the appropriate one must exist in the object.<br><br>	Verb applies are usually added to the lib<br>objects that are appropriate. For example, let's take<br>the "press" verb. When you "<span
 style="font-weight: bold;">push the button</span>", the parser<br>checks with the verb daemon, VERBS_D, to find out if<br>"push" means anything. Sure enough, it's a synonym for<br>"press", so the parser checks out the rules for press. <br><br>	Eventually the parser decides all the t's are<br>crossed and i's are dotted, and it's time to actually <br>see whether the "button" you're talking about is <br>pressable. It does this by calling the following apply<br>in the button object:<br><br
 style="color: rgb(0, 102, 0); font-weight: bold;"><span
 style="color: rgb(0, 102, 0); font-weight: bold;">direct_press_obj(&lt;the button object is the argument here&gt;)</span><br><br>	If the button does not have this function,<br>or if the function returns 0, the parser errors, assuming<br>that you're trying to press something that isn't<br>supposed to be pressable. Therefore, if you're going to <br>make a button somewhere, or a wall or anything that<br>should do something when pushed, it will need to<br>have that function in it. The way it looks is something<br>like this:<br><br><br
 style="font-weight: bold; color: rgb(0, 102, 0);"><span
 style="font-weight: bold; color: rgb(0, 102, 0);">mixed direct_press_obj(object target) {</span><br
 style="font-weight: bold; color: rgb(0, 102, 0);"><span
 style="font-weight: bold; color: rgb(0, 102, 0);">    return CanPress(this_player());</span><br
 style="font-weight: bold; color: rgb(0, 102, 0);"><span
 style="font-weight: bold; color: rgb(0, 102, 0);">}</span><br><br>	Now, this gets complicated, because the CanPress()<br>fun is a function that checks to see whether the <br>relationship between the button, the presser, and the lib<br>permits the pressing.<br><br>	If you're going to have an object that is <br>pressed, it's going to be a right pain in the butt to<br>code all the necessary checks into that object. Fortunately,<br>you don't need to. If you make a pressable thing, you don't<br>need to code all that stuff yourself. Just have it<br>inherit LIB_PRESS, which is a file that already<br>contains the applies you need.<br><br>	But, we're not done. You'll need to understand<br>a couple more things to be able to construct your new verb.<br><br>	direct and indirect refer to the relationship<br>of two objects on a command line. If all you have is<br>"throw ball", there's no need to worry about object relationship.<br>But what if the command is "shoot nice guy eddy with pistol"?<br>Or, suppose the player types "shoot pistol at eddy"?<br><br>	The parser needs to differentiate between the two,<br>but it isn't nearly sophisticated enough to understand the<br>concept of who is acting on whom. The parser just needs to<br>know which is first and which is second. therefore, in<br>LIB_SELL you'll see:<br><br><br><span
 style="font-weight: bold; color: rgb(0, 102, 0);">mixed direct_sell_obj_to_liv()</span><br><br>where the direct object is obj and the indirect object<br>is liv, and:<br><br><span
 style="font-weight: bold; color: rgb(0, 102, 0);">mixed indirect_sell_liv_obj()</span><br><br>where the direct object is liv and the indirect object is obj.<br>Again, this is not English grammar, it's parser grammar.<br><br><br><br><span
 style="font-weight: bold; text-decoration: underline;"><a name="5"></a>References</span><br><br>	Though sparse, there are other sources of information<br>on verbs and the parser. Some of it is quite thorough but<br>incomprehensible. Some of it is crystal clear but not applicable<br>to the current version of MudOS and/or Dead Souls.<br><br>	You're encouraged to visit the following sites<br>to gain more insight into the parser, but be warned that I<br>cannot vouch for the intelligibility or applicability of<br>their information.<br><br>	Please let me know if you find others.<br><br><br><a
 href="http://www.dnd.utwente.nl/%7Ekrimud/Docs/NMAdmin/Parser/">http://www.dnd.utwente.nl/~krimud/Docs/NMAdmin/Parser/</a><br><br><a
 href="http://www.islandsofmyth.org/wiz/parser_guide.html"><br>http://www.islandsofmyth.org/wiz/parser_guide.html</a><br><br><br>	Within the mud, you should read and understand the<br>parser related man page, specifically:<br><br><span
 style="font-weight: bold;">man parse_command</span><br><br><br>	<br><a
 href="index.html">Dead Souls Homepage</a><br><br></big></pre>
</body>
</html>
